//
//  CalculatorBrain.swift
//  Calculator
//
//  Created by Apple on 2018/9/17.
//  Copyright © 2018年 Apple. All rights reserved.
//

import Foundation

class CalculatorBrain
{
    private enum Op {
        //操作数
        case Operand(Double)
        //一元操作符
        case UnaryOperation(String, (Double) -> Double)
        //二元操作符
        case BinaryOperation(String, (Double,Double) -> Double)
    }
    
    //声明一个数字栈，完整写法：var operandStack=Array<Op>()
    private var operandStack=[Double]()
    
    //声明一个操作栈，完整写法：var operationStack=Array<Op>()
    private var operationStack=[String]()
    
    //已知运算的字典 完整写法：var knownOps=Dictionary<String:Op>()
    private var knownOps=[String:Op]()
    
    init(){
        knownOps["*"] = Op.BinaryOperation("*"){$0*$1}
        knownOps["/"] = Op.BinaryOperation("/"){$0/$1}
        knownOps["+"] = Op.BinaryOperation("+"){$0+$1}
        knownOps["-"] = Op.BinaryOperation("-"){$0-$1}
        
    }
    
    func performOperation(operation:(Double,Double)->Double!) -> Double! {
        if(operandStack.count>=2){
            print(operandStack.count)
            let op2 = operandStack.removeLast()
            let op1 = operandStack.removeLast()
            return operation(op1,op2)
        }else if(operandStack.count==1){
            print(operandStack.count)
            let op2 = operandStack.removeLast()
            let op1 = op2;
            return operation(op1,op2)
        }else{
            return 0;
        }
    }
    
    //计算结果=
    func evaluate() -> Double! {
        //print ("\(operandStack)>>>\(operationStack)")
        let operation = operationStack.removeLast()
        switch operation {
        case "÷": return performOperation(operation: divide)
        case "×": return performOperation(operation: multiply)
        case "−": return performOperation(operation: subtract)
        case "+": return performOperation(operation: add)
        default:  break;
        }
        return nil;
    }
    
    //加法
    func add(op1:Double,op2:Double)->Double{
        
        return op1+op2;
    }
    //减法
    func subtract(op1:Double,op2:Double)->Double{
        
        return op1-op2;
    }
    //乘法
    func multiply(op1:Double,op2:Double)->Double{
        
        return op1*op2;
    }
    //除法
    func divide(op1:Double,op2:Double)->Double! {
        if op2 == 0 {
            return nil;
        }
        return op1/op2;
    }
   
    
    //操作数入栈
    func pushOperand(operand:Double) {
        print (operand);
        operandStack.append(operand)
        
        print ("\(operandStack)>>>\(operationStack)")
    }
    
    func isOperandStackFull(symbol:String) -> Double! {
        if operandStack.count == 2 {
            if let result = evaluate() {
                operandStack.append(result)
                return result;
            }
        }
        return nil;
    }
    
    //操作符操入栈
    func pushOperation(symbol:String) {
        if operandStack.count == 0 {
            operandStack.append(0);
        }
        
        print (symbol);

        operationStack.removeAll()
        operationStack.append(symbol)
        
        print ("\(operandStack)>>>>>>\(operationStack)")
    }
    
    func reset(){
        operandStack.removeAll();
        operationStack.removeAll();
    }
    
}
